package cn.virens.common.boot.mybatis.autoconfig;

import cn.virens.common.mybatis.datasource.DynamicDataSourceImpl;
import cn.virens.common.util.exception.APIException;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import org.dromara.hutool.core.collection.CollUtil;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;

public class DynamicDataSourceWarp extends DynamicDataSourceImpl implements InitializingBean, DisposableBean {
    private DynamicDataSourceProperties properties;

    public DynamicDataSourceWarp(DynamicDataSourceProperties properties) {
        this.init(this.properties = properties);
    }

    /**
     * 填充主数据源
     */
    private void initMaster(Map<String, DynamicDataSourceDruid> map) throws APIException {
        if (masterDataSource == null && map != null && properties.getPrimary() != null) {
            this.masterDataSource = map.get(properties.getPrimary());
        }
        if (masterDataSource == null && map != null && map.size() == 1) {
            this.masterDataSource = CollUtil.getFirst(map.values());
        }
        if (masterDataSource == null && map != null) {
            this.masterDataSource = map.get("master");
        }
    }

    /**
     * 填充从数据源
     */
    private void initSlave(Map<String, DynamicDataSourceDruid> map) throws APIException {
        for (DruidDataSource druidDataSource : map.values()) {
            if (this.masterDataSource != druidDataSource) {
                this.addSlaveDataSource(druidDataSource);
            }
        }
    }

    private void init(DynamicDataSourceProperties properties) throws APIException {
        this.initMaster(properties.getDatasources());
        this.initSlave(properties.getDatasources());
    }

    @Autowired(required = false)
    public void autoAddFilters(List<Filter> filters) throws APIException {
        this.properties.addFilters(filters);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.properties.initAll();
    }

    @Override
    public void destroy() throws Exception {
        this.properties.closeAll();
    }
}
